#ifndef _AGM_PERIPHERALS_H
#define _AGM_PERIPHERALS_H

#include "gpio.h"

#define PERIPHERAL_NAME(__TYPE, __ID) (__TYPE##__ID)
#define PERIPHERAL_NAME_(__TYPE, __ID) PERIPHERAL_NAME(__TYPE, __ID)

/////////////////////////////////////////////////////////////////////////////////////////

#define PERIPHERAL_FCB_ENABLE(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
}

#define PERIPHERAL_WATCHDOG_ENABLE(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
}
#define PERIPHERAL_SPI_ENABLE(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_ENABLE(__PER##_CSN); \
  GPIO_AF_ENABLE(__PER##_SCK); \
  GPIO_AF_ENABLE(__PER##_SI_IO0); \
  GPIO_AF_ENABLE(__PER##_SO_IO1); \
}

#define PERIPHERAL_SPI_ENABLE_ALL(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_ENABLE(__PER##_CSN); \
  GPIO_AF_ENABLE(__PER##_SCK); \
  GPIO_AF_ENABLE(__PER##_SI_IO0); \
  GPIO_AF_ENABLE(__PER##_SO_IO1); \
  GPIO_AF_ENABLE(__PER##_WPN_IO2); \
  GPIO_AF_ENABLE(__PER##_HOLDN_IO3); \
}

#define PERIPHERAL_GPIO_ENABLE(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
}

#define PERIPHERAL_TIMER_ENABLE(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
}

#define PERIPHERAL_GPTIMER_ENABLE(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
}

#define PERIPHERAL_GPTIMER_ENABLE_ALL(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_ENABLE(__PER##_BRK); \
  GPIO_AF_ENABLE(__PER##_CH0); \
  GPIO_AF_ENABLE(__PER##_CH1); \
  GPIO_AF_ENABLE(__PER##_CH2); \
  GPIO_AF_ENABLE(__PER##_CH3); \
  GPIO_AF_ENABLE(__PER##_CHN0); \
  GPIO_AF_ENABLE(__PER##_CHN1); \
  GPIO_AF_ENABLE(__PER##_CHN2); \
  GPIO_AF_ENABLE(__PER##_CHN3); \
  GPIO_AF_ENABLE(__PER##_ETR); \
  GPIO_AF_ENABLE(__PER##_OCREF_CLR); \
}

#define PERIPHERAL_UART_ENABLE(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_ENABLE(__PER##_UARTRXD); \
  GPIO_AF_ENABLE(__PER##_UARTTXD); \
}

#define PERIPHERAL_UART_ENABLE_ALL(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_ENABLE(__PER##_UARTRXD); \
  GPIO_AF_ENABLE(__PER##_UARTTXD); \
  GPIO_AF_ENABLE(__PER##_NUARTCTS); \
  GPIO_AF_ENABLE(__PER##_NUARTRTS); \
}

#define PERIPHERAL_CAN_ENABLE(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_ENABLE(__PER##_RX0); \
  GPIO_AF_ENABLE(__PER##_TX0); \
}

#define PERIPHERAL_CAN_ENABLE_ALL(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_ENABLE(__PER##_RX0); \
  GPIO_AF_ENABLE(__PER##_TX0); \
  GPIO_AF_ENABLE(__PER##_INT_IN); \
}

#define PERIPHERAL_I2C_ENABLE(__PER) { \
  SYS_EnableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_ENABLE(__PER##_SCL); \
  GPIO_AF_ENABLE(__PER##_SDA); \
}

#define PERIPHERAL_DMAC_ENABLE(__PER) { \
  SYS_EnableAHBClock(AHB_MASK_##__PER); \
}

#define PERIPHERAL_USB_ENABLE(__PER) { \
  SYS_EnableAHBClock(AHB_MASK_##__PER); \
}

#define PERIPHERAL_MAC_ENABLE(__PER) { \
  SYS_EnableAHBClock(AHB_MASK_##__PER); \
  GPIO_AF_ENABLE(MAC0_MDC); \
  GPIO_AF_ENABLE(MAC0_MDIO); \
  GPIO_AF_ENABLE(MAC0_PHY_INTB); \
  GPIO_AF_ENABLE(MAC0_TX_CLK); \
  GPIO_AF_ENABLE(MAC0_TXD0); \
  GPIO_AF_ENABLE(MAC0_TXD1); \
  GPIO_AF_ENABLE(MAC0_TX_EN); \
  GPIO_AF_ENABLE(MAC0_RX_CLK); \
  GPIO_AF_ENABLE(MAC0_RXD0); \
  GPIO_AF_ENABLE(MAC0_RXD1); \
  GPIO_AF_ENABLE(MAC0_RX_ER); \
  GPIO_AF_ENABLE(MAC0_CRS); \
}

#define PERIPHERAL_MAC_ENABLE_ALL(__PER) { \
  SYS_EnableAHBClock(AHB_MASK_##__PER); \
  GPIO_AF_ENABLE(MAC0_MDC); \
  GPIO_AF_ENABLE(MAC0_MDIO); \
  GPIO_AF_ENABLE(MAC0_PHY_INTB); \
  GPIO_AF_ENABLE(MAC0_TX_CLK); \
  GPIO_AF_ENABLE(MAC0_TXD0); \
  GPIO_AF_ENABLE(MAC0_TXD1); \
  GPIO_AF_ENABLE(MAC0_TX_EN); \
  GPIO_AF_ENABLE(MAC0_RX_CLK); \
  GPIO_AF_ENABLE(MAC0_RXD0); \
  GPIO_AF_ENABLE(MAC0_RXD1); \
  GPIO_AF_ENABLE(MAC0_RX_ER); \
  GPIO_AF_ENABLE(MAC0_CRS); \
  GPIO_AF_ENABLE(MAC0_TXD2); \
  GPIO_AF_ENABLE(MAC0_TXD3); \
  GPIO_AF_ENABLE(MAC0_TX_ER); \
  GPIO_AF_ENABLE(MAC0_RXD2); \
  GPIO_AF_ENABLE(MAC0_RXD3); \
  GPIO_AF_ENABLE(MAC0_RX_DV); \
  GPIO_AF_ENABLE(MAC0_COL); \
}

#define PERIPHERAL_MAC_ENABLE_RMII PERIPHERAL_MAC_ENABLE(MAC0)
#define PERIPHERAL_MAC_ENABLE_MII  PERIPHERAL_MAC_ENABLE_ALL(MAC0)

#define PERIPHERAL_CRC_ENABLE(__PER) { \
  SYS_EnableAHBClock(AHB_MASK_##__PER); \
}

// Enable clock and commonly used pins for a peripheral
#define PERIPHERAL_ENABLE(__TYPE, __ID) PERIPHERAL_##__TYPE##_ENABLE(__TYPE##__ID)
#define PERIPHERAL_ENABLE_(__TYPE, __ID) PERIPHERAL_ENABLE(__TYPE, __ID)

// Enable clock and all useful pins for a peripheral
#define PERIPHERAL_ENABLE_ALL(__TYPE, __ID) PERIPHERAL_##__TYPE##_ENABLE_ALL(__TYPE##__ID)
#define PERIPHERAL_ENABLE_ALL_(__TYPE, __ID) PERIPHERAL_ENABLE_ALL(__TYPE, __ID)

/////////////////////////////////////////////////////////////////////////////////////////

#define PERIPHERAL_FCB_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
}

#define PERIPHERAL_WATCHDOG_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
}
#define PERIPHERAL_SPI_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_CSN); \
  GPIO_AF_DISABLE(__PER##_SCK); \
  GPIO_AF_DISABLE(__PER##_SI_IO0); \
  GPIO_AF_DISABLE(__PER##_SO_IO1); \
}

#define PERIPHERAL_SPI_DISABLE_ALL(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_CSN); \
  GPIO_AF_DISABLE(__PER##_SCK); \
  GPIO_AF_DISABLE(__PER##_SI_IO0); \
  GPIO_AF_DISABLE(__PER##_SO_IO1); \
  GPIO_AF_DISABLE(__PER##_WPN_IO2); \
  GPIO_AF_DISABLE(__PER##_HOLDN_IO3); \
}

#define PERIPHERAL_GPIO_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
}

#define PERIPHERAL_TIMER_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
}

#define PERIPHERAL_GPTIMER_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
}

#define PERIPHERAL_GPTIMER_DISABLE_ALL(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_BRK); \
  GPIO_AF_DISABLE(__PER##_CH0); \
  GPIO_AF_DISABLE(__PER##_CH1); \
  GPIO_AF_DISABLE(__PER##_CH2); \
  GPIO_AF_DISABLE(__PER##_CH3); \
  GPIO_AF_DISABLE(__PER##_CHN0); \
  GPIO_AF_DISABLE(__PER##_CHN1); \
  GPIO_AF_DISABLE(__PER##_CHN2); \
  GPIO_AF_DISABLE(__PER##_CHN3); \
  GPIO_AF_DISABLE(__PER##_ETR); \
  GPIO_AF_DISABLE(__PER##_OCREF_CLR); \
}

#define PERIPHERAL_UART_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_UARTRXD); \
  GPIO_AF_DISABLE(__PER##_UARTTXD); \
}

#define PERIPHERAL_UART_DISABLE_ALL(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_UARTRXD); \
  GPIO_AF_DISABLE(__PER##_UARTTXD); \
  GPIO_AF_DISABLE(__PER##_NUARTCTS); \
  GPIO_AF_DISABLE(__PER##_NUARTRTS); \
}

#define PERIPHERAL_CAN_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_RX0); \
  GPIO_AF_DISABLE(__PER##_TX0); \
}

#define PERIPHERAL_CAN_DISABLE_ALL(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_RX0); \
  GPIO_AF_DISABLE(__PER##_TX0); \
  GPIO_AF_DISABLE(__PER##_INT_IN); \
}

#define PERIPHERAL_I2C_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_SCL); \
  GPIO_AF_DISABLE(__PER##_SDA); \
}

#define PERIPHERAL_DMAC_DISABLE(__PER) { \
  SYS_DisableAHBClock(AHB_MASK_##__PER); \
}

#define PERIPHERAL_USB_DISABLE(__PER) { \
  SYS_DisableAHBClock(AHB_MASK_##__PER); \
}

#define PERIPHERAL_MAC_DISABLE(__PER) { \
  SYS_DisableAHBClock(AHB_MASK_##__PER); \
  GPIO_AF_DISABLE(MAC0_MDC); \
  GPIO_AF_DISABLE(MAC0_MDIO); \
  GPIO_AF_DISABLE(MAC0_PHY_INTB); \
  GPIO_AF_DISABLE(MAC0_TX_CLK); \
  GPIO_AF_DISABLE(MAC0_TXD0); \
  GPIO_AF_DISABLE(MAC0_TXD1); \
  GPIO_AF_DISABLE(MAC0_TX_EN); \
  GPIO_AF_DISABLE(MAC0_RX_CLK); \
  GPIO_AF_DISABLE(MAC0_RXD0); \
  GPIO_AF_DISABLE(MAC0_RXD1); \
  GPIO_AF_DISABLE(MAC0_RX_ER); \
  GPIO_AF_DISABLE(MAC0_CRS); \
}

#define PERIPHERAL_MAC_DISABLE_ALL(__PER) { \
  SYS_DisableAHBClock(AHB_MASK_##__PER); \
  GPIO_AF_DISABLE(MAC0_MDC); \
  GPIO_AF_DISABLE(MAC0_MDIO); \
  GPIO_AF_DISABLE(MAC0_PHY_INTB); \
  GPIO_AF_DISABLE(MAC0_TX_CLK); \
  GPIO_AF_DISABLE(MAC0_TXD0); \
  GPIO_AF_DISABLE(MAC0_TXD1); \
  GPIO_AF_DISABLE(MAC0_TX_EN); \
  GPIO_AF_DISABLE(MAC0_RX_CLK); \
  GPIO_AF_DISABLE(MAC0_RXD0); \
  GPIO_AF_DISABLE(MAC0_RXD1); \
  GPIO_AF_DISABLE(MAC0_RX_ER); \
  GPIO_AF_DISABLE(MAC0_CRS); \
  GPIO_AF_DISABLE(MAC0_TXD2); \
  GPIO_AF_DISABLE(MAC0_TXD3); \
  GPIO_AF_DISABLE(MAC0_TX_ER); \
  GPIO_AF_DISABLE(MAC0_RXD2); \
  GPIO_AF_DISABLE(MAC0_RXD3); \
  GPIO_AF_DISABLE(MAC0_RX_DV); \
  GPIO_AF_DISABLE(MAC0_COL); \
}

#define PERIPHERAL_MAC_DISABLE_RMII PERIPHERAL_MAC_DISABLE(MAC0)
#define PERIPHERAL_MAC_DISABLE_MII  PERIPHERAL_MAC_DISABLE_ALL(MAC0)

#define PERIPHERAL_CRC_DISABLE(__PER) { \
  SYS_DisableAHBClock(AHB_MASK_##__PER); \
}

// Disable clock and commonly used pins for a peripheral
#define PERIPHERAL_DISABLE(__TYPE, __ID) PERIPHERAL_##__TYPE##_DISABLE(__TYPE##__ID)
#define PERIPHERAL_DISABLE_(__TYPE, __ID) PERIPHERAL_DISABLE(__TYPE, __ID)

// Disable clock and all useful pins for a peripheral
#define PERIPHERAL_DISABLE_ALL(__TYPE, __ID) PERIPHERAL_##__TYPE##_DISABLE_ALL(__TYPE##__ID)
#define PERIPHERAL_DISABLE_ALL_(__TYPE, __ID) PERIPHERAL_DISABLE_ALL(__TYPE, __ID)

/////////////////////////////////////////////////////////////////////////////////////////

#define PERIPHERAL_FCB_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
}

#define PERIPHERAL_WATCHDOG_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
}
#define PERIPHERAL_SPI_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_CSN); \
  GPIO_AF_DISABLE(__PER##_SCK); \
  GPIO_AF_DISABLE(__PER##_SI_IO0); \
  GPIO_AF_DISABLE(__PER##_SO_IO1); \
}

#define PERIPHERAL_SPI_DISABLE_ALL(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_CSN); \
  GPIO_AF_DISABLE(__PER##_SCK); \
  GPIO_AF_DISABLE(__PER##_SI_IO0); \
  GPIO_AF_DISABLE(__PER##_SO_IO1); \
  GPIO_AF_DISABLE(__PER##_WPN_IO2); \
  GPIO_AF_DISABLE(__PER##_HOLDN_IO3); \
}

#define PERIPHERAL_GPIO_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
}

#define PERIPHERAL_TIMER_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
}

#define PERIPHERAL_GPTIMER_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
}

#define PERIPHERAL_GPTIMER_DISABLE_ALL(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_BRK); \
  GPIO_AF_DISABLE(__PER##_CH0); \
  GPIO_AF_DISABLE(__PER##_CH1); \
  GPIO_AF_DISABLE(__PER##_CH2); \
  GPIO_AF_DISABLE(__PER##_CH3); \
  GPIO_AF_DISABLE(__PER##_CHN0); \
  GPIO_AF_DISABLE(__PER##_CHN1); \
  GPIO_AF_DISABLE(__PER##_CHN2); \
  GPIO_AF_DISABLE(__PER##_CHN3); \
  GPIO_AF_DISABLE(__PER##_ETR); \
  GPIO_AF_DISABLE(__PER##_OCREF_CLR); \
}

#define PERIPHERAL_UART_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_UARTRXD); \
  GPIO_AF_DISABLE(__PER##_UARTTXD); \
}

#define PERIPHERAL_UART_DISABLE_ALL(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_UARTRXD); \
  GPIO_AF_DISABLE(__PER##_UARTTXD); \
  GPIO_AF_DISABLE(__PER##_NUARTCTS); \
  GPIO_AF_DISABLE(__PER##_NUARTRTS); \
}

#define PERIPHERAL_CAN_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_RX0); \
  GPIO_AF_DISABLE(__PER##_TX0); \
}

#define PERIPHERAL_CAN_DISABLE_ALL(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_RX0); \
  GPIO_AF_DISABLE(__PER##_TX0); \
  GPIO_AF_DISABLE(__PER##_INT_IN); \
}

#define PERIPHERAL_I2C_DISABLE(__PER) { \
  SYS_DisableAPBClock(APB_MASK_##__PER); \
  GPIO_AF_DISABLE(__PER##_SCL); \
  GPIO_AF_DISABLE(__PER##_SDA); \
}

#define PERIPHERAL_DMAC_DISABLE(__PER) { \
  SYS_DisableAHBClock(AHB_MASK_##__PER); \
}

#define PERIPHERAL_USB_DISABLE(__PER) { \
  SYS_DisableAHBClock(AHB_MASK_##__PER); \
}

#define PERIPHERAL_MAC_DISABLE(__PER) { \
  SYS_DisableAHBClock(AHB_MASK_##__PER); \
  GPIO_AF_DISABLE(MAC0_MDC); \
  GPIO_AF_DISABLE(MAC0_MDIO); \
  GPIO_AF_DISABLE(MAC0_PHY_INTB); \
  GPIO_AF_DISABLE(MAC0_TX_CLK); \
  GPIO_AF_DISABLE(MAC0_TXD0); \
  GPIO_AF_DISABLE(MAC0_TXD1); \
  GPIO_AF_DISABLE(MAC0_TX_EN); \
  GPIO_AF_DISABLE(MAC0_RX_CLK); \
  GPIO_AF_DISABLE(MAC0_RXD0); \
  GPIO_AF_DISABLE(MAC0_RXD1); \
  GPIO_AF_DISABLE(MAC0_RX_ER); \
  GPIO_AF_DISABLE(MAC0_CRS); \
}

#define PERIPHERAL_MAC_DISABLE_ALL(__PER) { \
  SYS_DisableAHBClock(AHB_MASK_##__PER); \
  GPIO_AF_DISABLE(MAC0_MDC); \
  GPIO_AF_DISABLE(MAC0_MDIO); \
  GPIO_AF_DISABLE(MAC0_PHY_INTB); \
  GPIO_AF_DISABLE(MAC0_TX_CLK); \
  GPIO_AF_DISABLE(MAC0_TXD0); \
  GPIO_AF_DISABLE(MAC0_TXD1); \
  GPIO_AF_DISABLE(MAC0_TX_EN); \
  GPIO_AF_DISABLE(MAC0_RX_CLK); \
  GPIO_AF_DISABLE(MAC0_RXD0); \
  GPIO_AF_DISABLE(MAC0_RXD1); \
  GPIO_AF_DISABLE(MAC0_RX_ER); \
  GPIO_AF_DISABLE(MAC0_CRS); \
  GPIO_AF_DISABLE(MAC0_TXD2); \
  GPIO_AF_DISABLE(MAC0_TXD3); \
  GPIO_AF_DISABLE(MAC0_TX_ER); \
  GPIO_AF_DISABLE(MAC0_RXD2); \
  GPIO_AF_DISABLE(MAC0_RXD3); \
  GPIO_AF_DISABLE(MAC0_RX_DV); \
  GPIO_AF_DISABLE(MAC0_COL); \
}

#define PERIPHERAL_MAC_DISABLE_RMII PERIPHERAL_MAC_DISABLE(MAC0)
#define PERIPHERAL_MAC_DISABLE_MII  PERIPHERAL_MAC_DISABLE_ALL(MAC0)

#define PERIPHERAL_CRC_DISABLE(__PER) { \
  SYS_DisableAHBClock(AHB_MASK_##__PER); \
}

// Disable clock and commonly used pins for a peripheral
#define PERIPHERAL_DISABLE(__TYPE, __ID) PERIPHERAL_##__TYPE##_DISABLE(__TYPE##__ID)
#define PERIPHERAL_DISABLE_(__TYPE, __ID) PERIPHERAL_DISABLE(__TYPE, __ID)

// Disable clock and all useful pins for a peripheral
#define PERIPHERAL_DISABLE_ALL(__TYPE, __ID) PERIPHERAL_##__TYPE##_DISABLE_ALL(__TYPE##__ID)
#define PERIPHERAL_DISABLE_ALL_(__TYPE, __ID) PERIPHERAL_DISABLE_ALL(__TYPE, __ID)

#endif
